/******************************************************************************
 *                                                                            *
 * Module:       Altera_UP_Avalon_VGA                                         *
 * Description:                                                               *
 *      This module controls VGA output for Altera's DE1 and DE2 Boards.      *
 *                                                                            *
 ******************************************************************************/

module Altera_UP_Avalon_VGA (
	// inputs
//	clk,
	vga_dac_clk,
//	vga_clk_inverted,
	reset,

`IF USE_PIXEL_MODE
	pixel_clk,
	pixel_address,
	pixel_chipselect,
	pixel_read,
	pixel_write,
	pixel_writedata,
`ENDIF

`IF USE_CHAR_MODE
	char_clk,
	char_address,
	char_chipselect,
	char_read,
	char_write,
	char_writedata,
`ENDIF

	// bidirectional
`IF USE_PIXEL_MODE
	SRAM_DQ,
`ENDIF

	// outputs
`IF USE_PIXEL_MODE
	pixel_readdata,
`ENDIF

`IF USE_CHAR_MODE
	char_readdata,
`ENDIF
//	waitrequest,

`IF USE_PIXEL_MODE
	SRAM_ADDR,
	SRAM_LB_N,
	SRAM_UB_N,
	SRAM_CE_N,
	SRAM_OE_N,
	SRAM_WE_N,
`ENDIF

//	VGA_CLK,
	VGA_BLANK,
	VGA_SYNC,
	VGA_HS,
	VGA_VS,
	VGA_R,
	VGA_G,
	VGA_B
);

/*****************************************************************************
 *                           Parameter Declarations                          *
 *****************************************************************************/

parameter PIXEL_ADDR_WIDTH	= 13;
parameter DAC_COLOR_WIDTH	= 10;

`IF USE_CHAR_MODE
parameter CHAR_ADDR_WIDTH				= 13;
parameter CHAR_DATA_WIDTH				= 16;
parameter CHAR_BUFFER_SIZE				= 4800;
parameter CHAR_ADDR_INCREMENT			= 13'h0001;

parameter Y_COORD_SMALL_OFFSET			= 4'h0;
parameter Y_COORD_LARGE_OFFSET			= 6'h00;

parameter CHAR_BITS						= 4;
parameter ENLARGE_CHAR					= 0;

// The Character Slave Bit Allocation
parameter X_BITS						= 7;
parameter Y_BITS						= 6;

// The Blank Char is space
parameter BLANK_CHAR					= 16'h0020;
`ENDIF

/*****************************************************************************
 *                             Port Declarations                             *
 *****************************************************************************/
// Inputs
input				vga_dac_clk;
//input				vga_clk_inverted;
input				reset;

`IF USE_PIXEL_MODE
input				pixel_clk;
input		[(PIXEL_ADDR_WIDTH-1):0]	pixel_address;
input				pixel_chipselect;
input				pixel_read;
input				pixel_write;
input		[31:0]	pixel_writedata;
`ENDIF

`IF USE_CHAR_MODE
input				char_clk;
input		[(CHAR_ADDR_WIDTH-1):0]		char_address;
input				char_chipselect;
input				char_read;
input				char_write;
input		[31:0]	char_writedata;
`ENDIF

// Bidirectionals
`IF USE_PIXEL_MODE
inout		[15:0]	SRAM_DQ;
`ENDIF

// Outputs
`IF USE_PIXEL_MODE
output		[31:0]	pixel_readdata;
`ENDIF

`IF USE_CHAR_MODE
output		[31:0]	char_readdata;
`ENDIF
//output				waitrequest;

`IF USE_PIXEL_MODE
output		[17:0]	SRAM_ADDR;
output				SRAM_LB_N;
output				SRAM_UB_N;
output				SRAM_CE_N;
output				SRAM_OE_N;
output				SRAM_WE_N;
`ENDIF

//output				VGA_CLK;
output				VGA_BLANK;
output				VGA_SYNC;
output				VGA_HS;
output				VGA_VS;
output		[(DAC_COLOR_WIDTH-1):0]	VGA_R;
output		[(DAC_COLOR_WIDTH-1):0]	VGA_G;
output		[(DAC_COLOR_WIDTH-1):0]	VGA_B;

/*****************************************************************************
 *                 Internal wires and registers Declarations                 *
 *****************************************************************************/
// Internal Wires
wire		[15:0]	data_to_avalon;
wire		[15:0]	data_to_vga;

wire				char_data;

wire		[10:1]	line_counter;
wire		[10:1]	pixel_counter;

// Internal Registers

// State Machine Registers

/*****************************************************************************
 *                         Finite State Machine(s)                           *
 *****************************************************************************/


/*****************************************************************************
 *                             Sequential logic                              *
 *****************************************************************************/


/*****************************************************************************
 *                            Combinational logic                            *
 *****************************************************************************/


/*****************************************************************************
 *                              Internal Modules                             *
 *****************************************************************************/

`IF USE_PIXEL_MODE
assign pixel_readdata = {data_to_avalon[15:13],data_to_avalon[10:8],data_to_avalon[4:2]};
`ENDIF

//`IF USE_CHAR_MODE
//assign char_readdata = {data_to_avalon[15:13],data_to_avalon[10:8],data_to_avalon[4:2]};
//`ENDIF

assign VGA_SYNC = 1'b0;

/*****************************************************************************
 *                              Internal Modules                             *
 *****************************************************************************/

`IF USE_PIXEL_MODE
Altera_UP_Pixel_Buffer Pixel_Buffer (
	// Inputs
	.clk							(pixel_clk),
	.clk_for_vga					(0),
	.reset							(reset),

	.colour_in						({pixel_writedata[8:6],pixel_writedata[8:7],pixel_writedata[5:3],pixel_writedata[5:3],pixel_writedata[2:0],pixel_writedata[2:1]}),
	.x_position_in					(pixel_address[6:0]),
	.y_position_in					(pixel_address[12:7]),
	.write_pixel_en					(pixel_write),
	.frame_complete_request			(0),
	
//	grid_colour_in,

	.line_counter					(line_counter),
	.pixel_counter					(pixel_counter),
	.end_of_frame					(),

//	vga_ctlr_address,
//	vga_ctlr_read,

	// Bi-Directional
	.SRAM_DQ						(SRAM_DQ),

	// Outputs
	.SRAM_ADDR						(SRAM_ADDR),
	.SRAM_LB_N						(SRAM_LB_N),
	.SRAM_UB_N						(SRAM_UB_N),
	.SRAM_CE_N						(SRAM_CE_N),
	.SRAM_OE_N						(SRAM_OE_N),
	.SRAM_WE_N						(SRAM_WE_N),

//	vga_ctlr_read_data

	.frame_complete_ack				(),
	
	.data_to_system					(data_to_avalon),
	.data_to_vga					(data_to_vga)
);
`ENDIF

`IF USE_CHAR_MODE
Altera_UP_Character_Buffer Character_Buffer (
	// Inputs
	.clk			(char_clk),
	.reset			(reset),

	.address		(char_address),
	.chipselect		(char_chipselect),
	.read			(char_read),
	.write			(char_write),
	.writedata		(char_writedata),

//	character,
	.x_coordinate	(pixel_counter),
	.y_coordinate	(line_counter),
	
	// Bidirectionals

	// Outputs
	.readdata		(char_readdata),
//	.readdatavalid	(),
//	.waitrequest	(),

	.character_data	(char_data)
);
defparam
	Character_Buffer.CHAR_ADDR_WIDTH		= CHAR_ADDR_WIDTH,
	Character_Buffer.CHAR_DATA_WIDTH		= CHAR_DATA_WIDTH,
	Character_Buffer.CHAR_BUFFER_SIZE		= CHAR_BUFFER_SIZE,
	Character_Buffer.CHAR_ADDR_INCREMENT	= CHAR_ADDR_INCREMENT,

	Character_Buffer.Y_COORD_SMALL_OFFSET	= Y_COORD_SMALL_OFFSET,
	Character_Buffer.Y_COORD_LARGE_OFFSET	= Y_COORD_LARGE_OFFSET,

	Character_Buffer.CHAR_BITS				= CHAR_BITS,
	Character_Buffer.ENLARGE_CHAR			= ENLARGE_CHAR,

	Character_Buffer.X_BITS					= X_BITS,
	Character_Buffer.Y_BITS					= Y_BITS,

	Character_Buffer.BLANK_CHAR				= BLANK_CHAR;
`ENDIF

Altera_UP_VGA_DAC VGA_DAC (
	// inputs
	.clk							(vga_dac_clk),
	.clk_inverted					(), // (vga_clk_inverted),
	.reset							(reset),

`IF USE_OVERLAY_MODE
	.red_data_to_vga_display		({10{char_data}} | {data_to_vga[15:11], data_to_vga[15:11]}),
	.green_data_to_vga_display		({10{char_data}} | {data_to_vga[10: 5], data_to_vga[10: 7]}),
	.blue_data_to_vga_display		({10{char_data}} | {data_to_vga[ 4: 0], data_to_vga[ 4: 0]}),
`ELSIF USE_PIXEL_MODE
//`IF USE_VGA_MODE
	.red_data_to_vga_display		({data_to_vga[15:11], data_to_vga[15:11]}),
	.green_data_to_vga_display		({data_to_vga[10: 5], data_to_vga[10: 7]}),
	.blue_data_to_vga_display		({data_to_vga[ 4: 0], data_to_vga[ 4: 0]}),
//`ENDIF
//`IF USE_CHAR_MODE
`ELSIF USE_CHAR_MODE
	.red_data_to_vga_display		({10{char_data}}),
	.green_data_to_vga_display		({10{char_data}}),
	.blue_data_to_vga_display		({10{char_data}}),
`ENDIF
	.data_valid						(1'b1),

	// bidirectional

	// outputs
	.line_counter					(line_counter),
	.pixel_counter					(pixel_counter),
	.active_display_interval		(),
	.consecutive_memory_addresses	(),
	.end_of_frame					(),

	// dac pins
	.vga_clk						(), //(VGA_CLK),
	.vga_blank						(VGA_BLANK),
	.vga_c_sync						(),
	.vga_h_sync						(VGA_HS),
	.vga_v_sync						(VGA_VS),
	.vga_red						(VGA_R),
	.vga_green						(VGA_G),
	.vga_blue						(VGA_B)
);

endmodule

